package com.pi.pro.xcmg.am.was.fac.service;


import com.pi.common.CodesConstants;
import com.pi.common.utils.StringUtils;
import com.pi.core.exchange.vo.CommonNameRegistryService;
import com.pi.pro.xcmg.am.common.XcmgAmConstants;
import com.pi.pro.xcmg.am.was.edi.wcs.common.WcsWasExchangeSupport;
import com.pi.pro.xcmg.am.was.edi.wcs.common.WcsWasXcmgExchangeConstants;
import com.pi.pro.xcmg.am.was.edi.wcs.dto.*;
import com.pi.pro.xcmg.am.was.edi.wcs.service.TasklistServiceProxy;
import com.pi.wms.common.WmsConstants;
import com.pi.wms.dto.act.TaskActionDto;
import com.pi.wms.dto.base.LocationLineDto;
import com.pi.wms.entity.TwmBasLocation;
import com.pi.wms.entity.TwtActTaskList;
import com.pi.wms.fac.LocationResolver;
import com.pi.wms.service.DivisionService;
import com.pi.wms.service.LocationService;
import com.pi.wms.service.TaskService;
import com.pi.wms.service.ZoneService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 *
 */
@Slf4j
@Service
public class WcsCustomWorkService {


    @Autowired
    private CommonNameRegistryService wcsNameRegistryService;

    @Autowired
    private ZoneService zoneService;

    @Autowired
    private LocationService locationService;

    @Autowired
    private DivisionService divisionService;

    @Autowired
    private LocationResolver locationResolver;

    @Autowired
    private TaskService taskService;

    @Autowired
    private WasCustomWorkService wasCustomWorkService;

    @Autowired
    private LedCustomWorkService ledCustomWorkService;


    private Map<Long, String> locationMap=new HashedMap();
    private Map<Long, Map<String, String>> divisionWcsWaslocationMap=new HashedMap();
    private Map<Long, String> srmPickLocationMap=new HashedMap();


    //-----------------------------------------------------------------------
    //
    //-----------------------------------------------------------------------

    /**
     *  执行
     * */
    //
    public CommonResultData execute(List<TwtActTaskList> tasks, TaskActionDto actionDto){
        CommonResultData resultData = WcsWasExchangeSupport.ok();
        if ((tasks==null)||(tasks.size()==0)){
            return resultData;
        }
        String m="";
        //
        Long divisionId=null;
        TasklistServiceProxy proxy = null;
        TransportTaskData transportTask=null;
        List<TransportTaskData> transportTasks=null;
        Map<String, String> containers=new HashMap<>();
        LocationLineDto fmloc=null;
        LocationLineDto toloc=null;
        Long tolocid=null;
        boolean crossflag=false;
        String pzonecode="";
        try{
            if ((actionDto!=null)
                    && (XcmgAmConstants.TASK_MODE_CROSS_ACTION.equalsIgnoreCase(actionDto.getWorkMode()))
                    && (!StringUtils.isNullOrBlank(actionDto.getLocationCode()))){
                fmloc=this.locationResolver.lookup(tasks.get(0).getDivisionId(), actionDto.getLocationCode().trim());
                if (fmloc!=null){
                    crossflag=true;
                }
            }

            //TODO:HU/202504
            //按division分组
            transportTasks=new ArrayList<>();
            for (TwtActTaskList t:tasks){
                if (t==null){
                    continue;
                }
                if (this.wasCustomWorkService.closed(t)){
                    continue;
                }
                if (containers.containsKey(t.getFromContainNumber())){
                    continue;
                }

                divisionId=t.getDivisionId();
                transportTask=WcsWasExchangeSupport.translateTo(t);
                if (transportTask!=null){
                    transportTask.setFromSite(this.takePointcode(t.getFromLocId()));
                    transportTask.setToSite(this.takePointcode(t.getToLocId()));

                    if ((WmsConstants.TASK_TYPE_PICK.equalsIgnoreCase(t.getType())) && (!crossflag)){
                        transportTask.setToSite(this.takeSrmdropPointcode(t.getFromLocId(), t.getToLocId()));
                    }
                    if ((WmsConstants.TASK_TYPE_PICK.equalsIgnoreCase(t.getType())) && (crossflag)){
                        transportTask.setType(WcsWasXcmgExchangeConstants.TASK_TYPE_TEXT_CROSS);
                        transportTask.setFromSite(this.takeSrmpickPointcode(fmloc.getLocationId()));
                        transportTask.setToSite(this.takePointcode(t.getToLocId()));
                        if (StringUtils.isNullOrBlank(transportTask.getOptionSite())){
                            pzonecode=this.wasCustomWorkService.locationZone(t.getToLocId());
                            transportTask.setOptionSite(WcsWasXcmgExchangeConstants.zonePickStations.get(pzonecode));
                        }
                    }
                    if (WmsConstants.TASK_TYPE_PUTAWAY.equalsIgnoreCase(t.getType())){
                        transportTask.setFromSite(this.takeSrmpickPointcode(t.getFromLocId()));
                    }
                    if (WmsConstants.TASK_TYPE_MOVE.equalsIgnoreCase(t.getType())){
                        tolocid=t.getToLocId();
                        if (t.getPlantoLocId()!=null){
                            tolocid=t.getPlantoLocId();
                        }
                        fmloc=this.locationResolver.lookup(t.getFromLocId());
                        toloc=this.locationResolver.lookup(tolocid);
                        if (WmsConstants.LOCATION_TYPE_BIN.equalsIgnoreCase(fmloc.getLocationType())){
                            if (!WmsConstants.LOCATION_TYPE_BIN.equalsIgnoreCase(toloc.getLocationType())){
                                transportTask.setToSite(this.takeSrmdropPointcode(t.getFromLocId(), t.getToLocId()));
                                if (StringUtils.isNullOrBlank(transportTask.getOptionSite())){
                                    transportTask.setOptionSite(this.takePointcode(toloc));
                                }
                            }
                        }else {
                            if (WmsConstants.LOCATION_TYPE_BIN.equalsIgnoreCase(toloc.getLocationType())){
                                transportTask.setFromSite(this.takeSrmpickPointcode(t.getFromLocId()));
                            }else {
                                transportTask.setFromSite(this.takeSrmpickPointcode(t.getFromLocId()));
                                if (StringUtils.isNullOrBlank(transportTask.getOptionSite())){
                                    transportTask.setOptionSite(this.takePointcode(toloc));
                                }
                                if (StringUtils.isNullOrBlank(transportTask.getFromSite())){
                                    transportTask.setFromSite(this.takePointcode(t.getFromLocId()));
                                }
                            }
                        }
                    }
                    if (WmsConstants.TASK_TYPE_COUNT.equalsIgnoreCase(t.getType())){
                        transportTask.setToSite(this.takeSrmdropPointcode(t.getFromLocId(), t.getToLocId()));
                    }
                    transportTasks.add(transportTask);
                }
                containers.put(t.getFromContainNumber(), CodesConstants.COMMON_FLAG_YES);
            }
            if ((transportTasks==null) || (transportTasks.size()<=0)){
                m = "cant found task";
                resultData = WcsWasExchangeSupport.error(m);
                return resultData;
            }
            //
            proxy = this.wcsNameRegistryService.takeProxy(XcmgAmConstants.CLIENT_ID_XCMG, divisionId, TasklistServiceProxy.class);
            if (proxy == null) {
                m = "not found task proxy";
                resultData = WcsWasExchangeSupport.error(m);
                return resultData;
            }
            resultData=proxy.execute(transportTasks);
        }catch (Exception e){
            e.printStackTrace();
        }
        return resultData;
    }

    public String showPickingTask(Long divisionId, String containerNumber, String locationCode){
        String m = "";
        if (StringUtils.isNullOrBlank(containerNumber)){
            return m;
        }
        if (StringUtils.isNullOrBlank(locationCode)){
            return m;
        }
        containerNumber=containerNumber.trim();
        locationCode=locationCode.trim();
        List<TwtActTaskList> tasks=null;
        int total=0;
        int index=0;
        String czonecode="";
        String pzonecode="";
        boolean arrival=false;
        try{
            tasks=this.taskService.queryWorkingTasks(WmsConstants.TASK_TYPE_PICK, containerNumber);
            if ((tasks==null)||(tasks.size()==0)){
                m = this.ledCustomWorkService.showPickStationPickSuccess(divisionId, locationCode, containerNumber, "拣货完成");
                return m;
            }
            if (this.wasCustomWorkService.livePickMode()){
                czonecode=this.wasCustomWorkService.currentZone(containerNumber);
                if (XcmgAmConstants.onlinePickZoneMap.containsKey(czonecode)){
                    arrival=true;
                }
            }
            total=tasks.size();
            tasks = this.wasCustomWorkService.sortPickTaskPickSequence(tasks);
            for (TwtActTaskList t:tasks){
                if (this.wasCustomWorkService.closed(t)){
                    continue;
                }
                if (this.wasCustomWorkService.livePickMode()){
                    if (arrival){
                        pzonecode=this.wasCustomWorkService.locationZone(t.getToLocId());
                        if (!pzonecode.equalsIgnoreCase(czonecode)){
                            continue;
                        }
                    }
                }
                index++;
                m = this.ledCustomWorkService.showPickStationPickTask(divisionId, locationCode, t, total, index);
                break;
            }
        }catch (Exception e){
            m="show picking task error."+e.getMessage();
            e.printStackTrace();
        }
        return m;
    }

    public String showCountTask(Long divisionId, String containerNumber, String locationCode){
        String m = "";
        if (StringUtils.isNullOrBlank(containerNumber)){
            return m;
        }
        if (StringUtils.isNullOrBlank(locationCode)){
            return m;
        }
        containerNumber=containerNumber.trim();
        locationCode=locationCode.trim();
        List<TwtActTaskList> tasks=null;
        int total=0;
        int index=0;
        String czonecode="";
        String pzonecode="";
        boolean arrival=false;
        try{
            tasks=this.taskService.queryWorkingTasks(WmsConstants.TASK_TYPE_COUNT, containerNumber);
            if ((tasks==null)||(tasks.size()==0)){
                m = this.ledCustomWorkService.showPickStationPickSuccess(divisionId, locationCode, containerNumber, "盘点完成");
                return m;
            }
            total=tasks.size();
            tasks = this.wasCustomWorkService.sortCountTaskCountingSequence(tasks);
            for (TwtActTaskList t:tasks){
                if (this.wasCustomWorkService.closed(t)){
                    continue;
                }
                index++;
                m = this.ledCustomWorkService.showPickStationCountTask(divisionId, locationCode, t, total, index);
                break;
            }
        }catch (Exception e){
            m="show counting task error."+e.getMessage();
            e.printStackTrace();
        }
        return m;
    }

    public String takePointcode(Long divisionId, String locationCode){
        String pointcode="";
        if (StringUtils.isNullOrBlank(locationCode)){
            return pointcode;
        }
        LocationLineDto loc=null;
        try{
            loc=this.locationResolver.lookup(divisionId, locationCode.trim());
            pointcode=this.takePointcode(loc);
        }catch (Exception e){
            e.printStackTrace();
        }
        return pointcode;
    }

    public String takePointcode(Long locationId){
        String pointcode="";
        LocationLineDto loc=null;
        try{
            pointcode=locationMap.get(locationId);
            if (!StringUtils.isNullOrBlank(pointcode)){
                return pointcode;
            }
            loc=this.locationResolver.lookup(locationId);
            if (loc==null){
                return pointcode;
            }
            pointcode=this.takePointcode(loc);
        }catch (Exception e){
            e.printStackTrace();
        }
        return pointcode;
    }

    public String takePointcode(LocationLineDto location){
        String pointcode="";
        if (location==null){
            return pointcode;
        }
        pointcode=location.getLocationCode();
        if (!StringUtils.isNullOrBlank(location.getRefCode03())){
            pointcode=location.getRefCode03().trim();
        }
        this.locationMap.putIfAbsent(location.getLocationId(), pointcode);
        return pointcode;
    }

    public String takeLocationcode(Long divisionId, String pointCode){
        String loccode="";
        if (StringUtils.isNullOrBlank(pointCode)){
            return loccode;
        }
        if (divisionId==null){
            divisionId=XcmgAmConstants.DIVISION_WH101_ID;
        }
        pointCode=pointCode.trim();
        Map<String, String> map=null;
        LocationLineDto loc=null;
        String prefix="";
        String ppointcode="";
        try{
            map = this.divisionWcsWaslocationMap.get(divisionId);
            if (map==null){
                map=new HashedMap();
                this.divisionWcsWaslocationMap.put(divisionId, map);
            }
            loccode=map.get(pointCode.trim());
            if (!StringUtils.isNullOrBlank(loccode)){
                return loccode;
            }
            //非立库/货架库位
            if (pointCode.length()<7){
                loccode = this.loadAllNoBinLocation(pointCode);
            }
            if (!StringUtils.isNullOrBlank(loccode)){
                return loccode;
            }
            //立库库位
            prefix="";
            ppointcode=pointCode;
            if (!ppointcode.startsWith("R")){
                prefix=XcmgAmConstants.divisionBinLocationPrefix.get(divisionId);
                if (StringUtils.isNullOrBlank(prefix)) {
                    prefix="R";
                }
                ppointcode=prefix+ppointcode;
            }
            loc=this.locationResolver.lookup(ppointcode);
            if (loc!=null){
                loccode=loc.getLocationCode();
                map.put(pointCode, loccode);
            }
            if (StringUtils.isNullOrBlank(loccode)){
                loccode=pointCode;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return loccode;
    }

    public String takeSrmDropStationLocationCode(LocationLineDto fromLocation, LocationLineDto toLocation){
        String loccode = "";
        if (toLocation==null){
            return loccode;
        }
        loccode=toLocation.getLocationCode();
        if (fromLocation==null){
            return loccode;
        }
        if (!WmsConstants.LOCATION_TYPE_BIN.equalsIgnoreCase(fromLocation.getLocationType())){
            return loccode;
        }
        if (WmsConstants.LOCATION_TYPE_BIN.equalsIgnoreCase(toLocation.getLocationType())){
            return loccode;
        }
        String keycode=this.divisionService.retrieve(fromLocation.getDivisionId());
        keycode=keycode+"/"+String.format("R%03d", fromLocation.getLaneNumber());
        keycode=keycode+"/"+this.zoneService.retrieve(toLocation.getZoneId());
        loccode=XcmgAmConstants.srmDropStationMap.get(keycode);
        if (StringUtils.isNullOrBlank(loccode)){
            loccode=toLocation.getLocationCode();
        }
        return loccode;
    }

    public String takeSrmdropPointcode(Long fromlocid, Long tolocid){
        String pointcode="";
        if ((fromlocid==null) || (tolocid==null)){
            return pointcode;
        }
        LocationLineDto fmloc=this.locationResolver.lookup(fromlocid);
        String loccode=this.takeSrmDropStationLocationCode(fmloc, this.locationResolver.lookup(tolocid));
        return this.takePointcode(fmloc.getDivisionId(), loccode);
    }

    public String takeSrmpickPointcode(Long fromlocid){
        String pointcode="";
        if (fromlocid==null){
            return pointcode;
        }
        pointcode=this.srmPickLocationMap.get(fromlocid);
        if (!StringUtils.isNullOrBlank(pointcode)){
            return pointcode;
        }
        LocationLineDto nextloc=this.wasCustomWorkService.takeSrmpickLocation(fromlocid);
        if (nextloc!=null){
            pointcode=this.takePointcode(nextloc);
            if (!StringUtils.isNullOrBlank(pointcode)){
                this.srmPickLocationMap.put(fromlocid, pointcode);
            }
        }
        return pointcode;
    }

    private String loadAllNoBinLocation(String curPointcode){
        List<TwmBasLocation> locs=null;
        Map<String, String> map=null;
        String pointcode="";
        String curloccode=curPointcode;
        try{
            locs=this.locationService.findByNoBinLocation();
            if ((locs==null) || (locs.size()==0)){
                return curloccode;
            }
            for (TwmBasLocation loc:locs){
                if (loc==null){
                    continue;
                }
                map=this.divisionWcsWaslocationMap.get(loc.getDivisionId());
                if (map==null){
                    map=new HashedMap();
                    this.divisionWcsWaslocationMap.put(loc.getDivisionId(), map);
                }
                pointcode=loc.getCode();
                if (!StringUtils.isNullOrBlank(loc.getRefCode03())){
                    pointcode=loc.getRefCode03().trim();
                }
                if (pointcode.equalsIgnoreCase(curPointcode)){
                    curloccode=loc.getCode();
                }
                map.put(pointcode, loc.getLocationCode());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return curloccode;
    }
}
